#!/usr/bin/env node
/**
 * @fileoverview 神岛代码项目创建工具的入口文件
 * 该文件负责处理用户交互，收集项目配置信息，并调用相关模块完成项目初始化
 */

import { default as chalk } from "chalk";
import { resolve, isAbsolute } from "path";
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import { install } from "./install.js";
import skeleton from "./skeleton.js";
import { ConfigWizard } from "./config-wizard.js";
import { errorHandler, ErrorType } from "./error-handler.js";

// 设置错误处理器
errorHandler.debug = process.env.DEBUG === "true";

/**
 * 项目创建的核心逻辑
 * @param {string} basepath - 项目基础路径
 * @param {object} answers - 配置答案
 * @param {object} selectedTemplate - 选定的模板
 */
async function createProject(basepath, answers, selectedTemplate = null) {
  try {
    // 显示项目创建进度
    console.log(chalk.cyan("\n🚀 项目创建进度："));
    console.log(chalk.dim("----------------------------------------"));

    // 步骤1：创建项目骨架
    console.log(chalk.cyan("[1/3] 🏗️  创建项目骨架"));
    console.log(chalk.dim("• 生成目录结构"));
    console.log(chalk.dim("• 配置基础文件"));
    console.log(chalk.dim("• 设置开发环境"));

    // 记录状态，但不创建日志文件
    console.log(chalk.blue("[信息] [项目创建] 开始创建项目骨架"));

    // 如果选择了项目模板，将模板信息添加到配置中
    if (selectedTemplate) {
      answers.template = { value: selectedTemplate.id };
    }

    await skeleton.skeleton(
      isAbsolute(basepath) ? basepath : resolve(process.cwd(), basepath),
      answers
    );
    console.log(chalk.green("✓ 项目骨架创建完成"));
    console.log(chalk.blue("[信息] [项目创建] 项目骨架创建完成"));

    // 步骤2：安装依赖
    console.log(chalk.cyan("\n[2/3] 📦 安装项目依赖"));
    console.log(chalk.dim("• 安装核心依赖"));
    console.log(chalk.dim("• 安装开发工具"));
    console.log(chalk.dim("• 配置构建脚本"));

    // 记录状态
    console.log(chalk.blue("[信息] [依赖安装] 开始安装项目依赖"));

    await install(basepath, answers);
    console.log(chalk.green("✓ 依赖安装完成"));

    // 步骤3：完成配置
    console.log(chalk.cyan("\n[3/3] ⚙️  完成项目配置"));
    console.log(chalk.dim("• 更新配置文件"));
    console.log(chalk.dim("• 设置开发环境"));
    console.log(chalk.dim("• 初始化版本控制"));
    console.log(chalk.green("✓ 配置完成"));

    console.log(chalk.dim("----------------------------------------"));
    console.log(chalk.blue("[信息] [项目创建] 项目创建完成"));
  } catch (error) {
    await errorHandler.handleError(
      error,
      ErrorType.UNKNOWN,
      "项目创建过程",
      () => {
        console.error(chalk.redBright("项目创建过程中发生错误："), error);
      }
    );
    process.exit(1);
  }

  // 显示项目创建成功的信息
  const path = resolve(process.cwd(), basepath);

  // 显示项目配置信息
  console.log(chalk.yellowBright("\n📋 ArenaPro项目配置信息"));
  console.log(chalk.dim("----------------------------------------"));
  console.log(chalk.cyan("📁 项目目录：") + " " + path);
  console.log(chalk.cyan("🔧 基础配置："));
  console.log(`   • 开发语言： ${answers.languageType.value}`);
  console.log(`   • 代码规范： ${answers.prettier.value}`);
  console.log(`   • 国际化： ${answers.i18n.value}`);
  console.log(
    `   • 项目类型：${answers.npmPackage.value}${
      answers.isServer.value ? ` (${answers.isServer.value})` : ""
    }`
  );

  if (selectedTemplate) {
    console.log(chalk.cyan("\n📋 项目模板："));
    console.log(`   • 模板名称：${selectedTemplate.name}`);
    console.log(`   • 模板特性：${selectedTemplate.features.join(", ")}`);
  }

  const entryExt = answers.languageType.value === "TypeScript" ? ".ts" : ".js";
  console.log(chalk.cyan("\n⚙️  共享代码："));
  console.log(`   • ${path}/shares/sharesApp${entryExt}`);

  if (!answers.isServer.value || answers.isServer.value === "服务端") {
    console.log(chalk.cyan("\n⚙️  服务端："));
    console.log(`   • ${path}/server/src/App${entryExt}`);
  }
  if (!answers.isServer.value || answers.isServer.value === "客户端") {
    console.log(chalk.cyan("\n⚙️  客户端："));
    console.log(`   • ${path}/client/src/clientApp${entryExt}`);
  }

  console.log(chalk.cyan("\n⚙️  配置文件："));
  console.log(`   • ${path}/dao3.config.json`);
  console.log(chalk.dim("----------------------------------------"));
  console.log(chalk.green("\n✨ 恭喜！项目创建成功！"));
}

/**
 * 主函数，用于引导用户进行项目创建的配置选择
 * 包含项目类型、编程语言、代码规范等配置项的交互式选择
 */
(async function main() {
  const argv = yargs(hideBin(process.argv))
    .option("name", {
      alias: "n",
      type: "string",
      description: "项目名称",
      coerce: (arg) => {
        if (arg && !/^[a-zA-Z0-9_./-]+$/.test(arg)) {
          throw new Error(
            "项目路径只能包含英文字母、数字、下划线、连字符、点 (.) 和斜杠 (/)"
          );
        }
        return arg;
      },
    })
    .option("type", {
      alias: "t",
      type: "string",
      description: "项目类型 (map 或 npm)",
      default: "map",
    })
    .option("lang", {
      alias: "l",
      type: "string",
      description: "开发语言 (ts 或 js)",
      default: "ts",
    })
    .option("prettier", {
      type: "boolean",
      description: "配置代码规范工具",
      default: false,
    })
    .option("i18n", {
      type: "boolean",
      description: "配置国际化",
      default: false,
    })
    .option("side", {
      type: "string",
      description: "项目包含的端 (both, server 或 client)",
      default: "both",
    })
    .option("dependentManner", {
      type: "string",
      description: "项目依赖方式 (npm 或 yarn 或 pnpm 或 bun)",
      default: "npm",
    })
    .help()
    .alias("help", "h").argv;

  try {
    if (argv.name) {
      // 非交互式模式
      const answers = {
        npmPackage: {
          value: argv.type === "npm" ? "神岛组件库" : "神岛地图项目",
        },
        languageType: {
          value: argv.lang === "js" ? "JavaScript" : "TypeScript",
        },
        prettier: { value: argv.prettier ? "配置" : "跳过" },
        i18n: { value: argv.i18n ? "配置" : "跳过" },
        isServer: {
          value:
            argv.type === "map"
              ? {
                  server: "仅服务端",
                  client: "仅客户端",
                  both: "服务端和客户端",
                }[argv.side] || "服务端和客户端"
              : "",
        },
        dependentManner: {
          value: argv.dependentManner,
        },
      };
      const basepath = argv.name;
      await createProject(basepath, answers);
    } else {
      const configWizard = new ConfigWizard({
        showTemplates: false,
        showAdvancedOptions: false,
      });

      const { answers, basepath, selectedTemplate } = await configWizard.run();
      await createProject(basepath, answers, selectedTemplate);
    }
  } catch (error) {
    await errorHandler.handleError(error, ErrorType.UNKNOWN, "项目创建", () => {
      console.log(chalk.red("\n❌ 创建项目失败"));
      console.log(chalk.dim("----------------------------------------"));
      console.error(chalk.red(`错误详情: ${error.message}`));
    });

    process.exit(1);
  }
})();
